"""
日志管理模块

作者：修炼者 (7457222@qq.com)
日期：2024-12-10

用法：
    from public.jygt_coder_loger import get_logger, setup_logging
    
    # 初始化日志系统
    setup_logging()
    
    # 获取日志记录器
    logger = get_logger(__name__)
    logger.debug('This is a debug message.')
"""
import logging
import os
import sys
from logging.handlers import RotatingFileHandler, TimedRotatingFileHandler
from typing import Optional, Dict, Any

# 缓存已创建的日志记录器
_logger_cache = {}
_root_logger = None

def find_project_root() -> str:
    """
    查找项目根目录
    
    Returns:
        项目根目录的路径
    """
    # 获取当前文件的目录
    current_dir = os.path.dirname(os.path.abspath(__file__))
    
    # 向上查找，直到找到包含src目录的目录
    while True:
        parent_dir = os.path.dirname(current_dir)
        if os.path.exists(os.path.join(current_dir, 'src')) or parent_dir == current_dir:
            return current_dir
        current_dir = parent_dir

def create_log_directory(log_file_path: str) -> None:
    """
    如果日志目录不存在，则创建日志目录
    
    Args:
        log_file_path: 日志文件路径
    """
    log_dir = os.path.dirname(log_file_path)
    if log_dir:
        os.makedirs(log_dir, exist_ok=True)

def get_log_level(level_name: str) -> int:
    """
    将日志级别名称转换为对应的日志级别
    
    Args:
        level_name: 日志级别名称
        
    Returns:
        日志级别常量
    """
    levels = {
        'DEBUG': logging.DEBUG,
        'INFO': logging.INFO,
        'WARNING': logging.WARNING,
        'ERROR': logging.ERROR,
        'CRITICAL': logging.CRITICAL
    }
    return levels.get(level_name.upper(), logging.INFO)

def configure_formatter() -> logging.Formatter:
    """
    配置日志格式化器
    
    Returns:
        配置好的日志格式化器
    """
    return logging.Formatter(
        '%(process)d - %(thread)d - %(levelname)s - %(asctime)s - %(name)s - %(filename)s:%(lineno)d - %(message)s'
    )

def setup_logging(config: Dict[str, Any] = None) -> None:
    """
    设置全局日志配置
    
    Args:
        config: 日志配置字典，可选
    """
    global _root_logger
    
    if _root_logger is not None:
        return
    
    # 默认配置
    log_config = {
        'LOG_LEVEL': 'INFO',
        'LOG_FILE': 'log/jygt_coder.log',
        'MAX_BYTES': 10 * 1024 * 1024,  # 10MB
        'BACKUP_COUNT': 5,
        'USE_CONSOLE': True,
        'USE_ROTATING': True,
        'USE_TIMED': False
    }
    
    # 更新配置
    if config:
        log_config.update(config)
    
    # 从环境变量获取配置
    log_config['LOG_LEVEL'] = os.getenv('JYGT_LOG_LEVEL', log_config['LOG_LEVEL'])
    log_config['LOG_FILE'] = os.getenv('JYGT_LOG_FILE', log_config['LOG_FILE'])
    
    # 获取项目根目录
    try:
        project_root = find_project_root()
    except FileNotFoundError:
        project_root = os.getcwd()
    
    # 构建日志文件的绝对路径
    log_file_path = os.path.join(project_root, log_config['LOG_FILE'])
    create_log_directory(log_file_path)
    
    # 配置根日志记录器
    _root_logger = logging.getLogger()
    _root_logger.setLevel(get_log_level(log_config['LOG_LEVEL']))
    
    # 清除现有处理器
    for handler in _root_logger.handlers[:]:
        _root_logger.removeHandler(handler)
    
    # 添加格式化器
    formatter = configure_formatter()
    
    # 添加控制台处理器
    if log_config['USE_CONSOLE']:
        console_handler = logging.StreamHandler(sys.stdout)
        console_handler.setFormatter(formatter)
        _root_logger.addHandler(console_handler)
    
    # 添加文件处理器
    if log_config['USE_ROTATING']:
        rotating_handler = RotatingFileHandler(
            log_file_path,
            maxBytes=log_config['MAX_BYTES'],
            backupCount=log_config['BACKUP_COUNT']
        )
        rotating_handler.setFormatter(formatter)
        _root_logger.addHandler(rotating_handler)
    
    if log_config['USE_TIMED']:
        timed_handler = TimedRotatingFileHandler(
            log_file_path,
            when='midnight',
            interval=1,
            backupCount=7
        )
        timed_handler.setFormatter(formatter)
        _root_logger.addHandler(timed_handler)
    
    # 记录初始化信息
    _root_logger.info(f"Logging initialized: level={log_config['LOG_LEVEL']}, file={log_file_path}")

def get_logger(name: str) -> logging.Logger:
    """
    获取指定名称的日志记录器
    
    Args:
        name: 日志记录器名称
        
    Returns:
        配置好的日志记录器
    """
    # 确保全局日志已初始化
    if _root_logger is None:
        setup_logging()
    
    # 从缓存获取或创建新的日志记录器
    if name not in _logger_cache:
        logger = logging.getLogger(name)
        _logger_cache[name] = logger
    
    return _logger_cache[name]